package com.siwei.mes.service.experiment.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.siwei.mes.common.query.PageQuery;
import com.siwei.mes.common.util.DateHelper;
import com.siwei.mes.common.util.JsonUtils;
import com.siwei.mes.common.util.NullUtils;
import com.siwei.mes.common.util.UploadFlagUtils;
import com.siwei.mes.config.CompanyConfigInterceptor;
import com.siwei.mes.config.UidUtils;
import com.siwei.mes.entity.AssociationStorage;
import com.siwei.mes.entity.ShxhSynchronizedata;
import com.siwei.mes.entity.UploadLaboratoryEntity;
import com.siwei.mes.entity.dto.SupplierCompanyMaterialsSelfSupplyDto;
import com.siwei.mes.entity.erp.Itemorder;
import com.siwei.mes.entity.erp.Rwdextra;
import com.siwei.mes.entity.erp.RwdextraInfo;
import com.siwei.mes.entity.experiment.*;
import com.siwei.mes.entity.experiment.cement.CementQdcd;
import com.siwei.mes.entity.experiment.concrete.batch.ConcreteKyqd;
import com.siwei.mes.entity.laboratory.*;
import com.siwei.mes.entity.materials.Materials;
import com.siwei.mes.entity.materials.MaterialsSpecConfig;
import com.siwei.mes.entity.mixproportion.MixProportion;
import com.siwei.mes.entity.order.Order;
import com.siwei.mes.entity.sync.tc.SupplyTask;
import com.siwei.mes.entity.sync.tc.Waybill;
import com.siwei.mes.entity.system.*;
import com.siwei.mes.entity.vo.CreateMaterialsExperimentVo;
import com.siwei.mes.entity.vo.ExperimentBatchVo;
import com.siwei.mes.entity.vo.ExperimentVo;
import com.siwei.mes.enums.*;
import com.siwei.mes.enums.laboratory.ReportIdEnum;
import com.siwei.mes.handler.ExperimentFactory;
import com.siwei.mes.handler.service.ExperimentFactoryService;
import com.siwei.mes.mapper.AssociationStorageMapper;
import com.siwei.mes.mapper.ShxhSynchronizedataMapper;
import com.siwei.mes.mapper.erp.ItemorderMapper;
import com.siwei.mes.mapper.erp.RwdextraMapper;
import com.siwei.mes.mapper.experiment.*;
import com.siwei.mes.mapper.laboratory.ImportListMapper;
import com.siwei.mes.mapper.laboratory.PrintReportMapper;
import com.siwei.mes.mapper.laboratory.WTConsignMapper;
import com.siwei.mes.mapper.laboratory.WTSampleMapper;
import com.siwei.mes.mapper.materials.MaterialsMapper;
import com.siwei.mes.mapper.materials.MaterialsSpecConfigMapper;
import com.siwei.mes.mapper.materials.SupplierCompanyMapper;
import com.siwei.mes.mapper.materials.SupplierCompanyMaterialsMapper;
import com.siwei.mes.mapper.mixProportion.MixProportionMapper;
import com.siwei.mes.mapper.syncTc.SupplyTaskMapper;
import com.siwei.mes.mapper.syncTc.WaybillMapper;
import com.siwei.mes.mapper.system.SignatureMapper;
import com.siwei.mes.mapper.system.TestProjectInfoMapper;
import com.siwei.mes.mapper.system.UserMapper;
import com.siwei.mes.service.erp.ItemorderService;
import com.siwei.mes.service.experiment.ExperimentDetailService;
import com.siwei.mes.service.experiment.ExperimentMessageService;
import com.siwei.mes.service.experiment.ExperimentService;
import com.siwei.mes.service.sync.tc.SupplyTaskService;
import com.siwei.mes.service.system.*;
import com.siwei.mes.sync.config.SyncProcessorService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.siwei.mes.common.exception.handler.MessageHandler.assertTrue;

/**
 * 试验台账(Experiment)表服务实现类
 *
 * @author linzi
 * @since 2023-12-18 22:11:47
 */
@Slf4j
@Service
public class ExperimentServiceImpl implements ExperimentService {
    @Resource
    private ExperimentMapper experimentMapper;
    @Resource
    private AuthService authService;
    @Resource
    private EquipmentService equipmentService;
    @Resource
    private TemperatureAndHumidityService temperatureAndHumidityService;
    @Resource
    private ExperimentSampleSmokeMapper experimentSampleSmokeMapper;
    @Resource
    private ExperimentFactory experimentFactory;
    @Resource
    private ExperimentDetailMapper experimentDetailMapper;
    @Resource
    private ExperimentSampleTestProjectMapper experimentSampleTestProjectMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private CheckQuickConfigMapper checkQuickConfigMapper;
    @Resource
    private CheckBatchConfigMapper checkBatchConfigMapper;
    @Resource
    private ExperimentMessageMapper experimentMessageMapper;
    @Resource
    private TestProjectInfoMapper testProjectInfoMapper;
    @Resource
    private ExperimentWaybillMapper experimentWaybillMapper;
    @Resource
    private ExperimentSupplyTaskMapper experimentSupplyTaskMapper;
    @Resource
    private WaybillMapper waybillMapper;
    @Resource
    private SupplyTaskMapper supplyTaskMapper;
    @Resource
    private MaterialsMapper materialsMapper;
    @Resource
    private ItemorderMapper itemorderMapper;
    @Resource
    private RwdextraMapper rwdextraMapper;
    @Resource
    private ExperimentTaskMapper experimentTaskMapper;
    @Resource
    private ExperimentMessageService experimentMessageService;
    @Resource
    private ExperimentItemorderMapper experimentItemorderMapper;
    @Resource
    private MaterialsSpecConfigMapper materialsSpecConfigMapper;
    @Resource
    private ExperimentGenConfigMapper experimentGenConfigMapper;
    @Resource
    private SupplyTaskService supplyTaskService;
    @Resource
    private ExperimentDetailService experimentDetailService;
    @Resource
    private UserService userService;
    @Resource
    private MixProportionMapper mixProportionMapper;
    @Resource
    private SupplierCompanyMapper supplierCompanyMapper;

    @Value("${deptName}")
    private String experimentDept;

    @Resource
    private PrintReportMapper printReportMapper;
    @Resource
    private ExperimentCheckItemorderMapper experimentCheckItemorderMapper;
    @Resource
    private ExperimentCheckWaybillMapper experimentCheckWaybillMapper;
    @Resource
    private ShxhSynchronizedataMapper shxhSynchronizedataMapper;
    @Resource
    private WTSampleMapper wtSampleMapper;
    @Resource
    private CompanyConfigService companyConfigService;
    @Resource
    private SupplierCompanyMaterialsMapper supplierCompanyMaterialsMapper;
    @Resource
    private AssociationStorageMapper associationStorageMapper;
    @Resource
    private ImportListMapper importListMapper;
    @Resource
    private WTConsignMapper consignMapper;

    @Resource
    private ItemorderService itemorderService;
    @Resource
    private SyncProcessorService syncProcessorService;
    @Resource
    private ExperimentSignatureMapper experimentSignatureMapper;
    @Resource
    private SignatureMapper signatureMapper;

    @Override
    public Long createConcrete(Experiment entity) {
        List<String> rolePermission = new ArrayList<>();
        rolePermission.add(RoleEnum.TESTER.getCode());
        rolePermission.add(RoleEnum.TESTER_DIRECTOR.getCode());
        rolePermission.add(RoleEnum.CHIEF_ENGINEER.getCode());
        rolePermission.add(RoleEnum.TEAM_LEADER.getCode());
        assertTrue(!rolePermission.contains(authService.getLoginUserRole()), "您暂无权限操作");

        /**这里只处理混凝土的  如果是原材料相关的直接不处理了*/
        if (!entity.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            log.info("这里只处理混凝土的新增试验委托");
            assertTrue("该接口不处理原材料相关的试验委托");
        }
        assertTrue(CollectionUtil.isEmpty(entity.getTestProjectCodeList()), "请选择至少一个试验项目");
        List<MixProportion> mixProportionList = mixProportionMapper.getList(new MixProportion().setProportionPhb(entity.getPhb()));
        assertTrue(CollectionUtils.isEmpty(mixProportionList) || mixProportionList.size() == 0, "配合比编号不存在");
        /** 龄期赋值 */
        entity.setLq(mixProportionList.get(0).getProportionLq());
        MaterialsSpecConfig materialsSpecConfig = materialsSpecConfigMapper.loadById(entity.getSpecId());
        if (materialsSpecConfig != null) {
            entity.setMaterialsName(materialsSpecConfig.getMaterialsName());
            entity.setMaterialsSpecs(materialsSpecConfig.getMaterialsSpec());
            if (StringUtils.isNotEmpty(materialsSpecConfig.getMaterialAbbreviation())) {
                entity.setSampleLevel(materialsSpecConfig.getMaterialAbbreviation() + materialsSpecConfig.getMaterialsSpec());
                entity.setMaterialAbbreviation(materialsSpecConfig.getMaterialAbbreviation());
            } else {
                entity.setSampleLevel(materialsSpecConfig.getMaterialsName() + materialsSpecConfig.getMaterialsSpec());
                /**简称没有直接赋值全称*/
                entity.setMaterialAbbreviation(materialsSpecConfig.getMaterialsName());
            }
            /**这里只处理混凝土的  混凝土的只需要规格 C5-C100*/
            if (materialsSpecConfig.getMaterialsType().equals(MaterialsEnum.CONCRETE.getCode())) {
                entity.setSampleLevel(materialsSpecConfig.getMaterialsSpec());
            }
        }
        entity.init(true);
        /*entity.setEntrustTime(new Date());*/
        entity.setCreateType(CreateTypeEnum.NEW_CHECK.getCode());
        this.payloadOtherInfo(entity, entity.getTestProjectCodeList());
        /**固定赋值为抽检**/
        entity.setEntrustReasonCode(EnturstReasonEnum.CJ.getCode());
        entity.setEntrustReasonName(EnturstReasonEnum.CJ.getName());
        CompanyConfig companyConfig = CompanyConfigInterceptor.getCompanyConfig(1);
        entity.setCertificateNo(companyConfig.getCompanyRecord());

        if (entity.getEntrustTime() != null) {
            entity.setMoldingTime(entity.getEntrustTime());
        }

        experimentMapper.insertSelective(entity);
        initExperimentTestProject(entity, entity.getTestProjectCodeList());
        if (entity.getTestProjectCodeList().size() == 1 && entity.getTestProjectCodeList().contains(TestProjectEnum.CONCRETE_PARAM_XNBG_LLZHL.getCode())) {
            /** 协会相关信息，通过企业配置信息赋值**/
            String sampleNo = UidUtils.genNoNumberToYearStr(GenerateCodeEnum.KLLZ_SAMPLENO.getCode(), "%06d", "12");
            String consignId = UidUtils.genNoNumberToYearStr(GenerateCodeEnum.KLLZ_CONSIGNID.getCode(), "%06d", "12");
            String kllzReportId = GenerateCodeEnum.KLLZ_REPORTID.getCode() + DateHelper.getYear() + UidUtils.genNoNumber(GenerateCodeEnum.KLLZ_REPORTID.getCode(), "%05d");
            entity.setSampleNo(sampleNo);
            entity.setReportNo(kllzReportId);
            entity.setReportDate(new Date());
            //新增对应关系
            experimentMapper.updateByPrimaryKeySelective(entity);

            /**根据试验委托id查询是否存在*/
            ShxhSynchronizedata shxhInfo = shxhSynchronizedataMapper.selectByExperimentIdOne(entity.getId());

            ShxhSynchronizedata synchronizedata = new ShxhSynchronizedata().setSampleId(sampleNo)
                    .setSampleNo(sampleNo).setConsignId(consignId).setExperimentId(entity.getId());
            if (shxhInfo != null) {
                synchronizedata.setId(shxhInfo.getId());
                shxhSynchronizedataMapper.updateByPrimaryKeySelective(synchronizedata);
            } else {
                synchronizedata.setId(null);
                shxhSynchronizedataMapper.insertSelective(synchronizedata);
            }
        }
        /**新增试验台账消息通知记录*/
        experimentMessageService.saveExperimentMessage(entity);
        return entity.getId();
    }

    @Override
    public Long createRawMaterials(Experiment entity) {
        entity.tcInit(true);
        entity.setEntrustTime(new Date());
        entity.setCreateType(CreateTypeEnum.JOB_CHECK.getCode());
        entity.setEntrustReasonCode(EnturstReasonEnum.CJ.getCode());
        entity.setEntrustReasonName(EnturstReasonEnum.CJ.getName());
        this.payloadOtherInfo(entity, entity.getTestProjectCodeList());
        experimentMapper.insertSelective(entity);
        initExperimentTestProject(entity, entity.getTestProjectCodeList());

        /**新增试验台账消息通知记录*/
        experimentMessageService.saveExperimentMessage(entity);
        return entity.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Experiment update(Experiment entity) {
        Experiment experiment = experimentMapper.loadById(entity.getId());
        assertTrue(experiment == null, "试验台账信息不存在");
        if (CheckEnum.BATCH.getCode().equals(entity.getCheckType())) {
            this.checkRolePermission();
        }
        entity.init(false);
        /**只有混凝土类型才校验成型日期*/
        if (experiment.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            assertTrue(ObjectUtils.isEmpty(entity.getMoldingTime()), "请输入成型日期");
        }
        /**这里设置已经是已保存状态*/
        entity.setIsSaveOrFinish(1);
        //修改报告编号 同步修改协会信息存储信息
        if (StringUtils.isNotBlank(entity.getReportNo())) {
            List<AssociationStorage> associationStorageList = associationStorageMapper.getList(new AssociationStorage().setExperimentId(experiment.getId()));
            if (associationStorageList == null || associationStorageList.isEmpty()) {
                AssociationStorage storage = new AssociationStorage()
                        .setExperimentId(experiment.getId())
                        .setGradeId(null)
                        .setSampleId(StringUtils.isNotBlank(entity.getSampleId()) ? Long.valueOf(entity.getSampleId()) : null)
                        .setSpecId(null)
                        .setReportId(entity.getReportNo());
                associationStorageMapper.insertSelective(storage);
            } else {
                AssociationStorage storage = associationStorageList.get(0);
                storage.setReportId(entity.getReportNo());
                associationStorageMapper.updateByPrimaryKeySelective(storage);
            }
        }
        experimentMapper.updateByPrimaryKeySelective(entity);
        return entity;
    }

    @Override
    public void delete(Long id) {
        Experiment experiment = experimentMapper.loadById(id);
        assertTrue(experiment == null, "试验台账信息不存在");

        assertTrue(experiment.getExperimentStatus().equals(ExperimentStatusEnum.FINISH.getCode()), "委托已完成，无法作废！");
        assertTrue(experiment.getExperimentStatus().equals(ExperimentStatusEnum.CANCEL.getCode()), "委托已作废，无法作废！");

        /**这里判断是否上传到协会 如果上传到协会的不允许作废*/
        assertTrue(StringUtils.isNotBlank(experiment.getSampleId()), "该委托已上传至协会，无法作废！");

        experiment.setExperimentStatus(ExperimentStatusEnum.CANCEL.getCode());
        experiment.init(false);
        experimentMapper.updateByPrimaryKeySelective(experiment);

        /**需要清空对应关联关系*/
        if (experiment.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            experimentCheckItemorderMapper.deleteByExperimentId(id);
        } else {
            log.info("开始清空experimentCheckWaybill表数据,delete方法,experimentId:【{}】", id);
            experimentCheckWaybillMapper.deleteByExperimentId(id);
        }

        /**如果是抗氯离子 作废需要给对应编号减一*/
        if (experiment.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            companyConfigService.reduceReportId(id, TestProjectEnum.CONCRETE_PARAM_XNBG_LLZHL.getCode());
        }
    }

    @Override
    public PageInfo<Experiment> getPage(PageQuery<Experiment, Experiment> query) {
        Experiment searchParam = query.getParams();
        Integer experimentType = searchParam.getExperimentType();
        List<Integer> experimentTypeList = searchParam.getExperimentTypeList();
        if (experimentTypeList == null || experimentTypeList.isEmpty()) {
            experimentTypeList = new ArrayList<>();
            if (experimentType != null) {
                experimentTypeList.add(experimentType);
            }
        }
        if (StpUtil.getLoginIdAsLong() != 99999999) {
            /**这里判断用户是否有对应的权限*/
            if (!experimentTypeList.isEmpty()) {
                assertTrue(!userService.getExperimentTypePermission(experimentTypeList), "该用户暂无权限查询数据");
            }
        }

        PageInfo<Experiment> pageInfo = PageHelper.startPage(query.getPageNum(), query.getPageSize())
                .doSelectPageInfo(() -> experimentMapper.getList(searchParam));


        if (pageInfo.getList().isEmpty()) {
            return pageInfo;
        }

        /**这里遍历所有的experimentId*/
        List<Long> experimentIdList = pageInfo.getList().stream().map(Experiment::getId).collect(Collectors.toList());
        /**查询对应试验委托详情信息返回对应是试验项目*/
        Map<Long, String> testProjectNameMap = experimentDetailService.getTestProjectNameMap(experimentIdList);

        for (Experiment experiment : pageInfo.getList()) {
            Long experimentId = experiment.getId();
            if (experiment.getFinistStatus() != null && "1".equals(experiment.getFinistStatus())) {
                experiment.setFinistStatus("已同步");
            }
            if (experiment.getFinistStatus() == null || experiment.getFinistStatus().isEmpty()) {

                //混凝土没有进料  所以用委托判断是否同步
                if (MaterialsEnum.CONCRETE.getCode().equals(experiment.getExperimentType())) {
                    if (experiment.getConsignId() != null && !experiment.getConsignId().isEmpty()) {
                        experiment.setFinistStatus("部分同步");
                    } else {
                        experiment.setFinistStatus("未同步");
                    }
                } else {
                    if (experiment.getImportId() != null && !experiment.getImportId().isEmpty()) {
                        experiment.setFinistStatus("部分同步");
                    } else {
                        experiment.setFinistStatus("未同步");
                    }
                }

            }
            /**赋值对应的代表数量*/
            this.payloadBehalfNumber(experiment);

            /**赋值试验项目信息*/
            if (testProjectNameMap.containsKey(experimentId)) {
                experiment.setTestProjectNameStr(testProjectNameMap.get(experimentId));
            }

            /**如果品控这边的报告编号为空 就赋值查询出来的报告编号*/
            if (StringUtils.isBlank(experiment.getReportNo())) {
                experiment.setReportNo(experiment.getReportId());
            }

            /**如果是混凝土类型的  获取对应工程名称*/
            if (experiment.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
                String projectNameStr = experimentTaskMapper.getProjectNameStr(experiment.getId());
                experiment.setProjectNameStr(projectNameStr);
            }
        }
        return pageInfo;
    }

    @Override
    public Experiment loadById(Long id) {
        Experiment experiment = experimentMapper.loadById(id);
        /**赋值对应的代表数量*/
        this.payloadBehalfNumber(experiment);
        return experiment;
    }

    @Override
    public List<Experiment> getAll(Experiment entity) {
        List<Experiment> list = experimentMapper.getList(entity);
        for (Experiment experiment : list) {
            /**赋值对应的代表数量*/
            this.payloadBehalfNumber(experiment);
        }
        return list;
    }

    /**
     * 赋值对应的代表数量
     *
     * @param experiment
     */
    private void payloadBehalfNumber(Experiment experiment) {
        if (experiment == null) {
            return;
        }
        /*判断是原材料还是混凝土*/
        if (MaterialsEnum.CONCRETE.getCode().equals(experiment.getExperimentType())) {
            experiment.setBehalfNumber(experiment.getRealBehalfNumber() == null ? experiment.getBehalfNumber() : experiment.getRealBehalfNumber());
        } else {
            /**这里存在拆单功能 直接用代表数量  不需要实时去累计*/
            List<Integer> splitTypeList = new ArrayList<>();
            splitTypeList.add(MaterialsEnum.ADMIXTURE.getCode());
            splitTypeList.add(MaterialsEnum.FINE.getCode());
            splitTypeList.add(MaterialsEnum.COARSE.getCode());
            splitTypeList.add(MaterialsEnum.CEMENT.getCode());
            if (splitTypeList.contains(experiment.getExperimentType())) {
                experiment.setBehalfNumber(experiment.getBehalfNumber() == null ? experiment.getRealMaterialNumber() : experiment.getBehalfNumber());
                experiment.setRealMaterialNumber(experiment.getBehalfNumber());
            } else {
                experiment.setBehalfNumber(experiment.getRealMaterialNumber() == null ? experiment.getBehalfNumber() : experiment.getRealMaterialNumber());
            }
        }
    }

    @Override
    //@Transactional(rollbackFor = Exception.class)
    public Experiment accept(Long id, boolean isCheckRole) {
        Experiment entity = experimentMapper.selectByPrimaryKey(id);
        assertTrue(entity == null, "试验台账信息不存在");
        /**新建委托不校验**/
        if (!CreateTypeEnum.NEW_CHECK.getCode().equals(entity.getCreateType())) {
            List<Materials> materialsList = materialsMapper.selectBySpecId(entity.getSpecId());
            assertTrue(CollectionUtil.isEmpty(materialsList) || entity.getSpecId() == null, "物料命名不规范，请前往物料规则菜单配置！");
        }
        if (CheckEnum.BATCH.getCode().equals(entity.getCheckType()) && isCheckRole) {
            this.checkRolePermission();
            entity.setAcceptPersonId(authService.getLoginUserId());
            entity.setAcceptPersonName(authService.getLoginUserName());
            entity.init(false);
        } else {
            entity.laboratoryInit(false);
        }
        entity.setAcceptTime(new Date());
        entity.setExperimentStatus(ExperimentStatusEnum.WAIT_SAMPLING.getCode());
        experimentMapper.updateByPrimaryKeySelective(entity);
        /**修改试验台账消息通知记录为已读*/
        experimentMessageMapper.updateState(entity.getId());
        return entity;
    }

    public void checkRolePermission() {
        List<String> rolePermission = new ArrayList<>();
        rolePermission.add(RoleEnum.TESTER.getCode());
        rolePermission.add(RoleEnum.TESTER_DIRECTOR.getCode());
        rolePermission.add(RoleEnum.CHIEF_ENGINEER.getCode());
        assertTrue(!rolePermission.contains(authService.getLoginUserRole()), "您暂无权限操作");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Experiment finish(Long id) {
        Experiment entity = experimentMapper.selectByPrimaryKey(id);
        assertTrue(entity == null, "试验台账信息不存在");

        /**只有混凝土类型才校验成型日期*/
        if (entity.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            assertTrue(ObjectUtils.isEmpty(entity.getMoldingTime()), "请输入成型日期");
        }
        if (CheckEnum.BATCH.getCode().equals(entity.getCheckType())) {
            this.checkRolePermission();
        }
        /**检查必填*/
        ExperimentFactoryService instance = experimentFactory.getInstance(entity.getExperimentType().toString());
        /**查询所有对应试验台账的详情信息*/
        List<ExperimentDetail> detailList = experimentDetailMapper.selectByExperimentId(id, null);
        String msg = instance.checkIsMustToExperimentDetail(detailList);
        if (StringUtils.isNotBlank(msg)) {
            assertTrue(msg);
            return entity;
        }

        entity.init(false);
        entity.setFinishPersonId(authService.getLoginUserId());
        entity.setFinishPersonName(authService.getLoginUserName());
        entity.setFinishTime(new Date());
        entity.setExperimentStatus(ExperimentStatusEnum.FINISH.getCode());

        entity.setExperimentPersonId(authService.getLoginUserId());
        entity.setExperimentPersonName(authService.getLoginUserName());
        entity.setExperimentTime(new Date());
        /**这里设置已经是已保存状态*/
        entity.setIsSaveOrFinish(1);
        /** 抗氯离子 生成报告编号和报告时间 如果是包含氯离子含量的，不做处理 李总说包含氯离子含量的数据都是错误数据 **/
        if (entity.getExperimentType() == MaterialsEnum.CONCRETE.getCode() && entity.getEntrustExperiment().equals("氯离子含量")) {
            entity.setReportNo(GenerateCodeEnum.KLLZ_REPORTID.getCode() + UidUtils.genNoNumberByYear(GenerateCodeEnum.KLLZ_REPORTID.getCode(), "%06d"));
            entity.setReportDate(new Date());
        }
        experimentMapper.updateByPrimaryKeySelective(entity);
        /**把抽样记录都变成已完成*/
        experimentSampleSmokeMapper.updateIsFinish(entity.getId());

        /**查询所有抽样记录 把抽样记录的处置人变成最后完成委托的人*/
        List<ExperimentSampleSmoke> sampleSmokeList = experimentSampleSmokeMapper.selectByExperimentId(id);
        for (ExperimentSampleSmoke sampleSmoke : sampleSmokeList) {
            sampleSmoke.init(false);
            sampleSmoke.setDisposerPersonId(authService.getLoginUserId());
            sampleSmoke.setDisposerPersonName(authService.getLoginUserName());
            experimentSampleSmokeMapper.updateByPrimaryKeySelective(sampleSmoke);
        }
        return entity;
    }

    @Override
    public void refuse(Long id) {
        Experiment entity = experimentMapper.selectByPrimaryKey(id);
        assertTrue(entity == null, "试验台账信息不存在");
        if (CheckEnum.BATCH.getCode().equals(entity.getCheckType())) {
            this.checkRolePermission();
        }
        entity.init(false);
        entity.setRefusePersonId(authService.getLoginUserId());
        entity.setRefusePersonName(authService.getLoginUserName());
        entity.setRefuseTime(new Date());
        entity.setExperimentStatus(ExperimentStatusEnum.REFUSE.getCode());
        experimentMapper.updateByPrimaryKeySelective(entity);
        /**修改试验台账消息通知记录为已读*/
        experimentMessageMapper.updateState(entity.getId());

        /**需要清空对应关联关系*/
        if (entity.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            experimentCheckItemorderMapper.deleteByExperimentId(id);
        } else {
            log.info("开始清空experimentCheckWaybill表数据,refuse方法，experimentId：【{}】", id);
            experimentCheckWaybillMapper.deleteByExperimentId(id);
        }

        /**如果是抗氯离子 作废需要给对应编号减一*/
        if (entity.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            companyConfigService.reduceReportId(id, TestProjectEnum.CONCRETE_PARAM_XNBG_LLZHL.getCode());
        }
    }

    @Override
    public Experiment getExperimentInfoByItemOrderInfo(Itemorder entity, Integer checkType, String entrustExperiment, Set<String> testProjectCodeList) {
        Experiment experiment = Itemorder.payloadExperiment(entity, MaterialsEnum.CONCRETE.getCode());
        experiment.setEntrustExperiment(entrustExperiment);
        experiment.setCheckType(checkType);
        /**组装其它信息*/
        this.payloadOtherInfo(experiment, testProjectCodeList);
        return experiment;
    }

    @Override
    public Experiment getExperimentInfoByRwdextraToOrder(Rwdextra rwdextra, Integer checkType, EnturstReasonEnum enturstReasonEnum, Order entity) {
        Experiment experiment = new Experiment();
        experiment.erpInit(true);
        experiment.setCheckType(checkType);
        experiment.setExperimentType(MaterialsEnum.CONCRETE.getCode());
        experiment.setEntrustTime(new Date());
        RwdextraInfo rwdextraInfo = rwdextra.getRwdextraInfo();
        if (rwdextraInfo != null) {
            experiment.setSampleLevel(rwdextraInfo.getFTpz());
            experiment.setMaterialsName(rwdextraInfo.getFTpz());
        }
        experiment.setBehalfNumber(0d);
        experiment.setEntrustReasonCode(enturstReasonEnum.getCode());
        experiment.setEntrustReasonName(enturstReasonEnum.getName());
        experiment.setEntrustExperiment(enturstReasonEnum.getName());
        experiment.setEntrustPersonId(entity.getCreater());
        experiment.setEntrustPersonName(entity.getCreaterName());
        /**组装其它信息*/
        this.payloadOtherInfo(experiment, null);
        return experiment;
    }

    @Override
    public Experiment getExperimentInfo(Integer checkType, EnturstReasonEnum enturstReasonEnum, String ypdj, String entrustExperiment, Set<String> testProjectCodeList) {
        Experiment experiment = new Experiment();
        experiment.setEntrustExperiment(entrustExperiment);
        experiment.phbInit(true);
        experiment.setCheckType(checkType);
        experiment.setExperimentType(MaterialsEnum.CONCRETE.getCode());
        experiment.setEntrustTime(new Date());
        experiment.setSampleLevel(ypdj);
        experiment.setMaterialsName(ypdj);
        experiment.setBehalfNumber(0d);
        experiment.setEntrustReasonCode(enturstReasonEnum.getCode());
        experiment.setEntrustReasonName(enturstReasonEnum.getName());

        if (StpUtil.isLogin()) {
            User entity = new User();
            entity.setId(StpUtil.getLoginIdAsLong());
            List<User> list = userMapper.getList(entity);
            experiment.setEntrustPersonId(StpUtil.getLoginIdAsLong());
            experiment.setEntrustPersonName(!list.isEmpty() ? list.get(0).getUserName() : "");
        }
        /**组装其他信息*/
        this.payloadOtherInfo(experiment, testProjectCodeList);
        return experiment;
    }

    /**
     * 组装其它信息  试验依据、判断依据、仪器设备、最后一条含水率配置
     *
     * @param experiment          试验委托信息
     * @param testProjectCodeList 试验项目集合
     */
    @Override
    public void payloadOtherInfo(Experiment experiment, Set<String> testProjectCodeList) {
        Integer checkType = experiment.getCheckType();//委托类型 1-快检 2-批检
        Integer projectCategory = experiment.getExperimentType();
        Set<String> experimentGistList = new HashSet<>();//试验依据集合
        Set<String> judgeGistList = new HashSet<>();//判断依据集合
        Set<String> entrustExperimentSet = new HashSet<>();//试验名称集合
        Set<String> equipmentNoList = new HashSet<>();//仪器设备

        experiment.setCuringMode("标准养护");
        /**如果委托部门为空就赋值系统参数配置的*/
        if (StringUtils.isBlank(experiment.getExperimentDept())) {
            experiment.setExperimentDept(experimentDept);
        }
        /**这里根据试验项目去查询配置的试验依据和判断依据  检查类型 1-快检 2-批检*/
        if (testProjectCodeList != null && !testProjectCodeList.isEmpty()) {
            if (CheckEnum.QUICK.getCode().equals(checkType)) {
                List<CheckQuickConfig> list = checkQuickConfigMapper.getList(new CheckQuickConfig().setTestProjectCodeList(testProjectCodeList).setProjectCategory(projectCategory));
                for (CheckQuickConfig config : list) {
                    if (StringUtils.isNotBlank(config.getExperimentGist())) {
                        List<String> experimentGists = Arrays.stream(config.getExperimentGist().split(";"))
                                .collect(Collectors.toList());
                        experimentGistList.addAll(experimentGists);
                    }
                    if (StringUtils.isNotBlank(config.getJudgeGist())) {
                        List<String> judgeGists = Arrays.stream(config.getJudgeGist().split(";"))
                                .collect(Collectors.toList());
                        judgeGistList.addAll(judgeGists);
                    }
                    if (StringUtils.isNotBlank(config.getEquipmentNo())) {
                        equipmentNoList.addAll(Arrays.asList(config.getEquipmentNo().split(";")));
                    }
                }
            } else if (CheckEnum.BATCH.getCode().equals(checkType)) {
                List<CheckBatchConfig> list = checkBatchConfigMapper.getList(new CheckBatchConfig().setTestProjectCodeList(testProjectCodeList).setProjectCategory(projectCategory));
                for (CheckBatchConfig config : list) {
                    if (StringUtils.isNotBlank(config.getExperimentGist())) {
                        List<String> experimentGist = Arrays.stream(config.getExperimentGist().split(";"))
                                .collect(Collectors.toList());
                        experimentGistList.addAll(experimentGist);
                    }
                    if (StringUtils.isNotBlank(config.getJudgeGist())) {
                        List<String> judgeGists = Arrays.stream(config.getJudgeGist().split(";"))
                                .collect(Collectors.toList());
                        judgeGistList.addAll(judgeGists);
                    }
                    if (StringUtils.isNotBlank(config.getEquipmentNo())) {
                        equipmentNoList.addAll(Arrays.asList(config.getEquipmentNo().split(";")));
                    }
                }
            }


            List<TestProjectInfo> testProjectInfoList = testProjectInfoMapper.selectByTestProjectCodeList(testProjectCodeList);
            for (TestProjectInfo testProjectInfo : testProjectInfoList) {
                entrustExperimentSet.add(testProjectInfo.getTestName());
            }
        }

        if (!equipmentNoList.isEmpty()) {
            String equipment = equipmentNoList.stream().map(String::valueOf).collect(Collectors.joining(";"));
            experiment.setEquipment(equipment);
        }

        /**委托试验*/
        if (!entrustExperimentSet.isEmpty()) {
            String entrustExperiment = entrustExperimentSet.stream().map(String::valueOf).collect(Collectors.joining(","));
            experiment.setEntrustExperiment(entrustExperiment);
        }

        /**试验依据*/
        if (!experimentGistList.isEmpty()) {
            String experimentGist = experimentGistList.stream().map(String::valueOf).collect(Collectors.joining(";"));
            experiment.setExperimentGist(experimentGist);
        }
        /**判断依据*/
        if (!judgeGistList.isEmpty()) {
            String judgeGist = judgeGistList.stream().map(String::valueOf).collect(Collectors.joining(";"));
            experiment.setJudgeGist(judgeGist);
        }

        /**获取最后一条含水率配置*/
        TemperatureAndHumidity lastInfo = temperatureAndHumidityService.getLastInfo(new TemperatureAndHumidity());
        if (lastInfo != null) {
            experiment.setTemperature(lastInfo.getTemperature());
            experiment.setHumidness(lastInfo.getHumidness());
        }
    }

    @Override
    public Experiment getExperimentInfoByWaybillInfo(Waybill entity, Integer checkType, String entrustExperiment, Integer experimentType, Set<String> testProjectCodeList) {
        Experiment experiment = Waybill.payloadExperimentWaybill(entity, experimentType);
        experiment.setEntrustExperiment(entrustExperiment);
        experiment.setCheckType(checkType);

        this.payloadOtherInfo(experiment, testProjectCodeList);
        return experiment;
    }

    @Override
    public int getAllCount(Experiment entity) {
        Experiment experiment = experimentMapper.loadById(entity.getId());
        if (ObjectUtils.isEmpty(entity.getId()) || experiment == null) {
            return 0;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        entity.setStartTime(sdf.format(experiment.getCreateTime()));
        /*判断混泥土和原材料*/
        if (!MaterialsEnum.CONCRETE.getCode().equals(entity.getExperimentType())) {
            String projectJson = authService.getLoginUserProjectJson();
            JSONArray jsonArray = JSONUtil.parseArray(projectJson);
            if (!jsonArray.isEmpty()) {
                List<Integer> experimentTypeList = new ArrayList<>();
                for (Object obj : jsonArray) {
                    Map<String, Object> projectJsonMap = BeanUtil.beanToMap(obj);
                    experimentTypeList.add(Integer.parseInt(projectJsonMap.get("no").toString()));
                }
                entity.setExperimentTypeList(experimentTypeList);
            } else {
                return 0;
            }
        }
        return 0;
    }

    @Override
    public void bindExperimentItemOrder(ExperimentVo vo) {
        /**绑定实验台账与小票关系*/
        Long experimentId = vo.getExperimentId();
        log.info("开始手动绑定委托小票，对应试验台账ID：{}", experimentId);
        /**绑定试验台账和运单的关系*/
        assertTrue(CollectionUtils.isEmpty(vo.getItemOrderIds()), "小票ID信息不存在");

        Experiment experiment = experimentMapper.loadById(experimentId);
        assertTrue(experiment == null, "试验委托信息不存在");
        Double behalfNumber = experiment.getBehalfNumber();//代表数量

        List<Itemorder> itemorderList = itemorderService.selectItidList(vo.getItemOrderIds());
        float totalWeight = itemorderList.stream().map(Itemorder::getScquantity).reduce((float) 0, Float::sum);
        log.info("绑定委托小票，绑定票据总重量：{}", totalWeight);

        /**抗渗抗氯离子不需要判断，抗压抗折：只判断阈值为按重量的先*/
        List<ExperimentDetail> experimentDetails = experimentDetailMapper.selectByExperimentId(experimentId, null);
        Set<String> testProjectCodeList = experimentDetails.stream().map(ExperimentDetail::getTestProjectCode).collect(Collectors.toSet());

        List<String> needTestCodeList = new ArrayList<>();
        needTestCodeList.add(TestProjectEnum.CONCRETE_PARAM_KYQD.getCode());
        needTestCodeList.add(TestProjectEnum.CONCRETE_PARAM_KZQD.getCode());
        /**如果这里是抗压*/
        if (testProjectCodeList.contains(TestProjectEnum.CONCRETE_PARAM_KYQD.getCode())) {
            ExperimentGenConfig config = experimentGenConfigMapper.selectOne(new ExperimentGenConfig().setCheckType(CheckEnum.BATCH.getCode())
                    .setTestCode(TestProjectEnum.CONCRETE_PARAM_KYQD.getCode()).setExperimentType(MaterialsEnum.CONCRETE.getCode()));

            assertTrue(config == null, "没有对应的抗压强度配置信息，不允许添加小票");
            assertTrue(config.getIsOpen() == null || config.getIsOpen() == 0, "暂未开启抗压强度配置项目，不允许添加小票");

            Integer checkRules = config.getCheckRules();
            if (checkRules == 2) {//按重量
                String checkThreshold = config.getCheckThreshold();
                if (behalfNumber + totalWeight > Float.parseFloat(checkThreshold)) {
                    log.info("混凝土绑定小票，按重量的阈值超出，不允许添加小票,之前的代表数量：【{}】，绑定票据总重量：【{}】", behalfNumber, totalWeight);
                    assertTrue("混凝土绑定小票，按重量的阈值超出，不允许添加小票");
                }
            }
        } else if (testProjectCodeList.contains(TestProjectEnum.CONCRETE_PARAM_KZQD.getCode())) {
            ExperimentGenConfig config = experimentGenConfigMapper.selectOne(new ExperimentGenConfig().setCheckType(CheckEnum.BATCH.getCode())
                    .setTestCode(TestProjectEnum.CONCRETE_PARAM_KZQD.getCode()).setExperimentType(MaterialsEnum.CONCRETE.getCode()));

            assertTrue(config == null, "没有对应的抗折强度配置信息，不允许添加小票");
            assertTrue(config.getIsOpen() == null || config.getIsOpen() == 0, "暂未开启抗折强度配置项目，不允许添加小票");

            Integer checkRules = config.getCheckRules();
            if (checkRules == 2) {//按重量
                String checkThreshold = config.getCheckThreshold();
                if (behalfNumber + totalWeight > Float.parseFloat(checkThreshold)) {
                    log.info("混凝土绑定小票，按重量的阈值超出，不允许添加小票,之前的代表数量：【{}】，绑定票据总重量：【{}】", behalfNumber, totalWeight);
                    assertTrue("混凝土绑定小票，按重量的阈值超出，不允许添加小票");
                }
            }
        }

        for (Integer itemOrderId : vo.getItemOrderIds()) {
            Itemorder itemorder = itemorderMapper.loadByItId(itemOrderId);
            assertTrue(itemorder == null, "小票信息不存在");
            /**新增试验台账对应小票数据*/
            ExperimentItemorder experimentItemorder = new ExperimentItemorder().setExperimentId(experimentId).setItemorderId(itemorder.getItid());
            if (experimentItemorderMapper.selectOne(experimentItemorder) == null) {
                experimentItemorderMapper.insertSelective(experimentItemorder);
            }

            Rwdextra rwdextra = rwdextraMapper.selectByFrwdh(itemorder.getFrwdh());
            if (rwdextra == null) {
                log.info("ERP供货任务信息不存在，直接跳过");
                continue;
            }
            ExperimentTask experimentTask = new ExperimentTask().setExperimentId(experimentId).setTaskId(rwdextra.getFrwdh());
            if (experimentTaskMapper.selectOne(experimentTask) == null) {
                experimentTask.setCreateTime(new Date());
                experimentTask.setReadTime(null);
                experimentTaskMapper.insertSelective(experimentTask);
                /**这里新增任务单的关联关系 给对应试验委托的isNewTask改为1*/
                log.info(this.getClass() + "新增任务单给对应isNewTask修改为1");
                experimentMapper.updateIsNewTask(experimentId, 1);


                /**这里判断是否已经上传到协会，如果没有上传到协会就不推送*/
                ShxhSynchronizedata shxhSynchronizedata = shxhSynchronizedataMapper.selectByExperimentIdOne(experimentId);
                if (shxhSynchronizedata != null && shxhSynchronizedata.getSampleId() != null) {
                    log.info(this.getClass().getName() + "新增任务单之后，推送协会！");
                    /**推送到协会，这里新增任务单 状态为自动上传*/
                    syncProcessorService.submitRequest(new UploadLaboratoryEntity().setExperimentId(Collections.singletonList(String.valueOf(experimentId))).setUploadState(1));
                }
            }
        }
        /**修改试验台账代表数量*/
        this.updateBehalfNumberByItemorder(experimentId);
    }

    /**
     * 修改代表方量
     *
     * @param experimentId
     */
    public void updateBehalfNumberByItemorder(Long experimentId) {
        /**修改这个试验台账的代表数量 == 所有跟这个试验台账相关的小票发货数量之和*/
        List<Itemorder> itemorderList = experimentItemorderMapper.selectByExperimentId(experimentId);
        double behalfNumber = itemorderList.stream().map(Itemorder::getScquantity).reduce((float) 0, Float::sum);
        Experiment updateInfo = new Experiment();
        updateInfo.setId(experimentId);
        updateInfo.setBehalfNumber(behalfNumber);
        updateInfo.erpInit(false);
        experimentMapper.updateByPrimaryKeySelective(updateInfo);
    }


    @Override
    public void saveExperimentWaybill(ExperimentVo vo) {
        log.info("开始手动绑定运单到委托单中，对应入参：【{}】", JSON.toJSONString(vo));
        Long experimentId = vo.getExperimentId();
        Experiment entity = experimentMapper.selectByPrimaryKey(experimentId);
        assertTrue(entity == null, "试验台账信息不存在");

        assertTrue(CollectionUtils.isEmpty(vo.getWaybillIds()), "运单ID信息不存在");

        /**查询对应原材料类型的阈值配置*/
        Integer experimentType = entity.getExperimentType();//类型
        Integer checkType = entity.getCheckType();//检查类型 1-快检 2-批检
        Double entityBehalfNumber = entity.getBehalfNumber();//代表数量
        log.info("试验委托对应类型：【{}】，对应检查类型：【{}】，对应代表数量：【{}】", experimentType, checkType, entityBehalfNumber);

        ExperimentGenConfig genConfig = experimentGenConfigMapper.getConfig(experimentType, checkType);
        assertTrue(genConfig == null, "没有对应的配置信息，不允许添加运单");
        assertTrue(genConfig.getIsOpen() == null || genConfig.getIsOpen() == 0, "暂未开启规格配置项目，不允许添加运单");


        Integer checkRules = genConfig.getCheckRules();//规则 1-车车都检  2-按重量  3-按车数  4-按时间
        String checkThreshold = genConfig.getCheckThreshold() == null ? "0" : genConfig.getCheckThreshold();//阈值  多少吨或者多少天  根据规则来走的
        log.info("对应阈值配置信息，规则：【{}】，阈值：【{}】", checkRules, checkThreshold);
        List<Waybill> waybillList = waybillMapper.getList(new Waybill().setIdList(vo.getWaybillIds()));

        if (checkRules == 2) {
            BigDecimal selectQuantity = waybillList.stream().map(Waybill::getSignQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);//选中的方量
            log.info("选中的方量：【{}】，之前的代表方量：【{}】", selectQuantity, entityBehalfNumber);
            /**委托的方量+选中的方量 如果大于阈值配置 直接提示不允许添加*/
            if (entityBehalfNumber + selectQuantity.doubleValue() > Double.parseDouble(checkThreshold)) {
                assertTrue("已超过对应阈值配置的方量，不允许添加运单！");
            }
        } else if (checkRules == 3) {
            int selectSize = waybillList.size();//选中的条数
            /**查询这个委托之前绑定的运单数量*/
            int beforeSize = experimentWaybillMapper.selectCount(new ExperimentWaybill().setExperimentId(experimentId));
            /**之前的条数+选中的运单数量 大于阈值配置的 直接提示不允许添加*/
            if (beforeSize + selectSize > Integer.parseInt(checkThreshold)) {
                assertTrue("已超过对应阈值配置的车数，不允许添加运单！");
            }
        }

        /**绑定试验台账和运单的关系*/
        String factory = "";
        String materialsId = "";
        String matterAbbreviation = "";
        String matterName = "";
        String matterSpecs = "";

        for (Waybill waybill : waybillList) {
            Long waybillId = waybill.getId();
            Materials select = new Materials().setMaterialType(entity.getExperimentType()).setMaterialName(waybill.getProjectName()).setMaterialSpecs(waybill.getProjectSpecs());
            List<Materials> materialsList = materialsMapper.select(select);
            if (CollectionUtils.isEmpty(materialsList)) {
                assertTrue(materialsList == null, "物料信息不存在");
            } else {
                if (StringUtils.isEmpty(materialsId)) {
                    materialsId = String.valueOf(materialsList.get(0).getId());
                    matterAbbreviation = materialsList.get(0).getMaterialAbbreviation();
                    matterName = materialsList.get(0).getMaterialName();
                    matterSpecs = materialsList.get(0).getMaterialSpecs();
                } else {
                    assertTrue(!materialsId.equals(String.valueOf(materialsList.get(0).getId())), "请选择同一物料的运单");
                }
            }
            ExperimentWaybill experimentWaybill = new ExperimentWaybill();
            experimentWaybill.setExperimentId(experimentId);
            experimentWaybill.setWaybillId(waybillId);
            experimentWaybill.setBehalfNumber(waybill.getSignQuantity() != null ? waybill.getSignQuantity().doubleValue() : BigDecimal.ZERO.doubleValue());
            experimentWaybillMapper.insertSelective(experimentWaybill);
            if (entity.getCheckType() == 1) {
                waybillMapper.updateByPrimaryKeySelective(new Waybill().setId(waybill.getId()).setIsQuick(1));
            } else {
                waybillMapper.updateByPrimaryKeySelective(new Waybill().setId(waybill.getId()).setIsBatch(1));
            }

            /**快检/批检与试验台账和供货任务的关系*/
            SupplyTask supplyTask = supplyTaskMapper.selectByTaskId(waybill.getSupplyTaskId());
            ExperimentSupplyTask experimentSupplyTask = new ExperimentSupplyTask().setExperimentId(vo.getExperimentId()).setSupplyTaskId(supplyTask.getId());
            if (experimentSupplyTaskMapper.selectOne(experimentSupplyTask) == null) {
                experimentSupplyTask.setCreateTime(new Date());
                experimentSupplyTask.setReadTime(null);
                experimentSupplyTaskMapper.insertSelective(experimentSupplyTask);

                /**这里新增任务单的关联关系 给对应试验委托的isNewTask改为1*/
                log.info(this.getClass().getName() + ".saveExperimentWaybill.class新增任务单给对应isNewTask修改为1");
                experimentMapper.updateIsNewTask(experimentId, 1);

                /**这里判断是否已经上传到协会，如果没有上传到协会就不推送*/
                ShxhSynchronizedata shxhSynchronizedata = shxhSynchronizedataMapper.selectByExperimentIdOne(experimentId);
                if (shxhSynchronizedata != null && shxhSynchronizedata.getSampleId() != null) {
                    log.info(this.getClass().getName() + ".saveExperimentWaybill.class新增任务单之后，推送协会！");
                    /**推送到协会，这里新增任务单 状态为自动上传*/
                    syncProcessorService.submitRequest(new UploadLaboratoryEntity().setExperimentId(Collections.singletonList(String.valueOf(experimentId))).setUploadState(1));
                }
            }
            factory = waybill.getFactory();
        }


        /**修改这个试验台账的代表数量 == 所有跟这个试验台账相关的运单签收数量之和*/
        Double behalfNumberSum = experimentWaybillMapper.selectTotalBehalfNumberByExperimentId(experimentId);
        log.info("查询对应试验委托的代表数量，试验委托id：【{}】，代表数量：【{}】", experimentId, behalfNumberSum);
        if (behalfNumberSum != null && behalfNumberSum > 0) {
            Experiment updateExperiment = new Experiment();
            updateExperiment.setId(experimentId);
            updateExperiment.setBehalfNumber(behalfNumberSum);
            updateExperiment.setFactory(factory);
            updateExperiment.setMaterialsId(materialsId);
            updateExperiment.setMatterAbbreviation(matterAbbreviation);
            updateExperiment.setMatterName(matterName);
            updateExperiment.setMatterSpecs(matterSpecs);
            updateExperiment.tcInit(false);
            experimentMapper.updateByPrimaryKeySelective(updateExperiment);
        }
    }

    @Override
    public void updateEquipmentInfo() {
        Map<String, String> equipmentInfoMap = equipmentService.getAllMaterialsTypeEquipmentInfo();
        for (Map.Entry<String, String> entry : equipmentInfoMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            MaterialsEnum materialsEnum = MaterialsEnum.selectByTypeProjectType(key);
            if (materialsEnum == null) {
                continue;
            }
            if (StringUtils.isBlank(value)) {
                continue;
            }
            experimentMapper.updateEquipmentInfo(materialsEnum.getCode(), value);
        }
    }

    @Override
    public void updateBatchByIds(ExperimentBatchVo vo) {
        List<Long> experimentIds = vo.getExperimentIds();
        for (Long experimentId : experimentIds) {
            assertTrue(experimentMapper.selectByPrimaryKey(experimentId) == null, "实验台帐信息不存在");
        }
        experimentMapper.updateBatchByIds(vo);
    }

    /**
     * 组装试验项目详情记录
     *
     * @param experiment
     */
    private void initExperimentTestProject(Experiment experiment, Set<String> testProjectCodeList) {
        if (testProjectCodeList.isEmpty()) {
            return;
        }
        /**查询所有试验项目信息*/
        List<TestProjectInfo> testProjectInfoList = testProjectInfoMapper.selectByTestProjectCodeList(testProjectCodeList);
        if (testProjectInfoList.isEmpty()) {
            return;
        }

        /**新增试验详情信息*/
        List<ExperimentDetail> detailList = new ArrayList<>();
        for (TestProjectInfo testProjectInfo : testProjectInfoList) {
            ExperimentDetail detail = new ExperimentDetail();
            detail.setExperimentId(experiment.getId());
            detail.setCheckType(experiment.getCheckType());
            detail.tcInit(true);
            detail.setTestProjectCode(testProjectInfo.getTestCode());
            detail.setTestProjectName(testProjectInfo.getTestName());
            detail.setObjJson(testProjectInfo.getObjJson());
            /**如果是粗骨料筛分析，需要重新组装json*/
            if (testProjectInfo.getTestCode().equals(TestProjectEnum.COARSE_AGGREGATE_PARAM_CGL_SFX.getCode())) {
                detail.setSfxJson(experiment, detail);
            }
            /**如果这里是混凝土抗压强度 并且对应mes的配合比龄期不为空  需要赋值龄期*/
            if (testProjectInfo.getTestCode().equals(TestProjectEnum.CONCRETE_PARAM_KYQD.getCode()) && StringUtils.isNotBlank(experiment.getLq())) {
                ConcreteKyqd concreteKyqd = detail.getObjJson().toJavaObject(ConcreteKyqd.class);
                concreteKyqd.setLq(experiment.getLq());
                detail.setObjJson(JsonUtils.beanToObject(concreteKyqd));
            }
            experimentDetailService.payloadOtherInfo(detail, testProjectInfo.getTestCode(), experiment.getExperimentType());
            detailList.add(detail);
        }
        experimentDetailMapper.insertList(detailList);


        /**这里要过滤掉抗渗等级  抗渗等级是有压试块的*/
        List<String> filterTestProjectCode = new ArrayList<>();
        filterTestProjectCode.add(TestProjectEnum.CONCRETE_PARAM_KSDJ.getCode());
        filterTestProjectCode.add(TestProjectEnum.CONCRETE_PARAM_KYQD.getCode());
        /**新增对应实验台账的抽样信息 */
        for (TestProjectInfo testProjectInfo : testProjectInfoList) {
            /**这里要查询不需要过滤的*/
            if (!filterTestProjectCode.contains(testProjectInfo.getTestCode())) {
                ExperimentSampleSmoke sampleSmoke = new ExperimentSampleSmoke();
                sampleSmoke.setId(null);
                sampleSmoke.tcInit(true);
                sampleSmoke.setExperimentId(experiment.getId());
                sampleSmoke.setSampleTime(new Date());
                sampleSmoke.setIsTestBlock(0);// 是否是试块 1-是 0-不是
                sampleSmoke.setSamplePersonName(experiment.getEntrustPersonName());
                sampleSmoke.setDisposerPersonName(experiment.getEntrustPersonName());
                sampleSmoke.setTestProjectCode(testProjectInfo.getTestCode());
                sampleSmoke.setTestProjectName(testProjectInfo.getTestName());
                sampleSmoke.setSampleUse(testProjectInfo.getTestName());
                if (testProjectInfo.getSampleQuantity() != null && testProjectInfo.getSampleQuantity() != -1) {
                    sampleSmoke.setSampleQuantity(testProjectInfo.getSampleQuantity());
                }
                experimentSampleSmokeMapper.insertSelective(sampleSmoke);
            }
        }

        if (experiment.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            /**如果是批检 并且在抽样试验项目配置中 有记录 直接生成对应的抽样记录 pk_experiment_sample_test_project*/
            List<ExperimentSampleSmoke> sampleSmokeList = new ArrayList<>();
            List<ExperimentSampleTestProject> sampleTestProjectList = experimentSampleTestProjectMapper.selectByTestProjectCodeList(testProjectCodeList);
            for (ExperimentSampleTestProject sampleTestProject : sampleTestProjectList) {
                Integer genNumber = sampleTestProject.getGenNumber();// 生成的条数
                JSONObject genJson = sampleTestProject.getGenJson();// 生成对应的json
                if (genJson.isEmpty() || genNumber == null || genNumber == 0) {
                    continue;
                }
                ExperimentSampleSmoke sampleSmoke = this.getExperimentSampleSmoke(sampleTestProject, experiment);
                sampleSmokeList.add(sampleSmoke);
            }
            /**保存抽样信息*/
            if (!sampleSmokeList.isEmpty()) {
                experimentSampleSmokeMapper.insertList(sampleSmokeList);
            }
        }
    }

    /**
     * 生成对应抽检信息
     *
     * @param sampleTestProject 抽检试验项目信息
     * @param experiment        试验台账信息
     * @return
     */
    private ExperimentSampleSmoke getExperimentSampleSmoke(ExperimentSampleTestProject sampleTestProject, Experiment experiment) {
        ExperimentSampleSmoke sampleSmoke = new ExperimentSampleSmoke();
        sampleSmoke.setId(null);
        sampleSmoke.erpInit(true);
        sampleSmoke.setExperimentId(experiment.getId());
        sampleSmoke.setSampleTime(new Date());
        sampleSmoke.setSampleTestProjectCode(sampleTestProject.getItemCode());
        sampleSmoke.setSampleTestProjectName(sampleTestProject.getItemName());
        sampleSmoke.setFreqNumber(sampleTestProject.getFreqNumber());
        sampleSmoke.setFreqUnit(sampleTestProject.getFreqUnit());
        sampleSmoke.setIsTestBlock(1);// 是否是试块 1-是 0-不是
        sampleSmoke.setTestProjectCode(sampleTestProject.getTestCode());
        sampleSmoke.setTestProjectName(sampleTestProject.getTestName());
        sampleSmoke.setSampleUse(sampleTestProject.getTestName());
        sampleSmoke.setSamplePersonName(experiment.getEntrustPersonName());
        sampleSmoke.setDisposerPersonName(experiment.getEntrustPersonName());
        return sampleSmoke;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createMaterialsExperiment(CreateMaterialsExperimentVo createMaterialsExperimentVo) {
        List<String> rolePermission = new ArrayList<>();
        rolePermission.add(RoleEnum.TESTER.getCode());
        rolePermission.add(RoleEnum.TESTER_DIRECTOR.getCode());
        rolePermission.add(RoleEnum.CHIEF_ENGINEER.getCode());
        rolePermission.add(RoleEnum.TEAM_LEADER.getCode());
        assertTrue(!rolePermission.contains(authService.getLoginUserRole()), "您暂无权限操作");
        /**先判断对应的检查是否是按数量*/
        Integer checkType = createMaterialsExperimentVo.getCheckType();//1-快检 2-批检
        if (checkType.equals(CheckEnum.QUICK.getCode())) {
            assertTrue("原材料相关新增试验委托不支持快检类型");
        }
        Integer experimentType = createMaterialsExperimentVo.getExperimentType();
        MaterialsEnum materialsEnum = MaterialsEnum.selectByCode(experimentType);
        assertTrue(experimentType.equals(MaterialsEnum.CONCRETE.getCode()), "不支持混凝土类型新增试验委托");
        /**如果是批检类型的  对应的生成规格设置一定要是按重量的  如果不是按重量的要提示*/
        ExperimentGenConfig genConfig = experimentGenConfigMapper.getConfig(experimentType, checkType);
        assertTrue(genConfig == null, "【" + materialsEnum.getName() + "】生成委托规则未配置");


        assertTrue(StringUtils.isBlank(genConfig.getCheckThreshold()), "委托规则对应阈值未配置");

        List<Integer> rulesList = Arrays.asList(1, 2, 4);
        Integer checkRules = genConfig.getCheckRules();
        if (!rulesList.contains(checkRules)) {
            assertTrue("原材料新建委托暂只支持车车都检或按重量或按时间来生成!");
        }

        /**查询材料信息*/
        MaterialsSpecConfig materialsSpecConfig = materialsSpecConfigMapper.loadById(createMaterialsExperimentVo.getSpecId());
        assertTrue(materialsSpecConfig == null, "材料信息不存在，请重新选择材料信息");
        /**查询物料信息*/
        List<Materials> materialsList = materialsMapper.selectBySpecId(createMaterialsExperimentVo.getSpecId());

        Double checkThreshold = Double.valueOf(genConfig.getCheckThreshold());//阈值
        Double forecastNumber = createMaterialsExperimentVo.getForecastNumber();//预报吨数

        if (checkRules == 2) {
            int count = (int) (forecastNumber / checkThreshold);//取整的次数
            for (int i = 0; i < count; i++) {
                log.info("手动生成原材料运单，按重量生成，对应数量：【{}】", checkThreshold);
                this.insertExperimentAndSupplyTask(createMaterialsExperimentVo, checkThreshold, materialsSpecConfig, materialsList);
            }

            double residueNumber = forecastNumber % checkThreshold;//剩下的方量
            if (residueNumber > 0) {
                log.info("手动生成原材料运单，按重量生成，对应剩下的数量：【{}】", residueNumber);
                this.insertExperimentAndSupplyTask(createMaterialsExperimentVo, residueNumber, materialsSpecConfig, materialsList);
            }
        } else if (checkRules == 4) {
            log.info("手动生成原材料运单，按时间生成，对应数量：【{}】", forecastNumber);
            /**这里是按时间的  传多少就生成多少*/
            this.insertExperimentAndSupplyTask(createMaterialsExperimentVo, forecastNumber, materialsSpecConfig, materialsList);
        } else if (checkRules == 1) {
            log.info("手动生成原材料运单，车车都检生成，对应数量：【{}】", forecastNumber);
            /**这里是按时间的  传多少就生成多少*/
            this.insertExperimentAndSupplyTask(createMaterialsExperimentVo, forecastNumber, materialsSpecConfig, materialsList);
        }
    }

    @Override
    public void updateBatchExperimentMatter() {
        /**根据生产厂商修改所有生产厂商简称**/
        experimentMapper.updateExperimentFactoryCalled();
        /**查询所有物料名称和物料规格都为空的试验台账**/
        List<Experiment> experiments = experimentMapper.getListMaterialsIsNull();
        for (Experiment experiment : experiments) {
            List<MaterialsSpecConfig> materialsSpecConfigList = materialsSpecConfigMapper.getList(new MaterialsSpecConfig().setMaterialsName(experiment.getMaterialsName()).setMaterialsSpec(experiment.getMaterialsSpecs()));
            if (CollectionUtil.isNotEmpty(materialsSpecConfigList) && materialsSpecConfigList.size() > 0) {
                List<Materials> materialsList = materialsMapper.selectBySpecId(materialsSpecConfigList.get(0).getId());
                /**正常取第一条数据赋值**/
                if (CollectionUtil.isNotEmpty(materialsList) && materialsList.size() == 1) {
                    Materials materials = materialsList.get(0);
                    experiment.setMatterName(materials.getMaterialName());
                    experiment.setMatterSpecs(materials.getMaterialSpecs());
                    experimentMapper.updateByPrimaryKeySelective(experiment);
                    continue;
                }
                /**如果有多条特殊处理**/
                /**矿渣粉**/
                if (experiment.getExperimentType().equals(MaterialsEnum.SLAG.getCode())) {
                    for (Materials materials : materialsList) {
                        if ("矿粉".equals(materials.getMaterialName())) {
                            experiment.setMatterName(materials.getMaterialName());
                            experiment.setMatterSpecs(materials.getMaterialSpecs());
                        }
                    }
                    experimentMapper.updateByPrimaryKeySelective(experiment);
                    continue;
                }
                /**细骨料**/
                if (experiment.getExperimentType().equals(MaterialsEnum.FINE.getCode())) {
                    for (Materials materials : materialsList) {
                        if ("砂1".equals(materials.getMaterialSpecs())) {
                            experiment.setMatterName(materials.getMaterialName());
                            experiment.setMatterSpecs(materials.getMaterialSpecs());
                        }
                    }
                    experimentMapper.updateByPrimaryKeySelective(experiment);
                    continue;
                }
                /**外加剂**/
                if (experiment.getExperimentType().equals(MaterialsEnum.ADMIXTURE.getCode())) {
                    for (Materials materials : materialsList) {
                        if ("SCG-S600".equals(materials.getMaterialSpecs())) {
                            experiment.setMatterName(materials.getMaterialName());
                            experiment.setMatterSpecs(materials.getMaterialSpecs());
                        }
                    }
                    experimentMapper.updateByPrimaryKeySelective(experiment);
                }
            }
        }
    }

    @Override
    public void updateBatchExperimentReportNo() {
        /**查询报告编号为空已完成的试验台账**/
        List<Experiment> experiments = experimentMapper.getListReportNoIsNull();
        for (Experiment experiment : experiments) {
            /**查询协会是否存在实验台帐报表信息**/
            PrintReport printReport = printReportMapper.queryByConSignID(experiment.getConsignId());
            if (printReport != null) {
                experiment.setReportNo(printReport.getReportID());
                experiment.setReportDate(printReport.getReportAuditTime());
                experimentMapper.updateByPrimaryKeySelective(experiment);
            }
        }
    }

    @Override
    public void updateBatchExperimentSelfSupply() {
        /** 查询所有是甲供的物料信息 **/
        List<SupplierCompanyMaterialsSelfSupplyDto> list = supplierCompanyMaterialsMapper.getMaterialsSelfSupplyList(new SupplierCompanyMaterialsSelfSupplyDto());
        /** 批量修改对应的试验台账信息 **/
        if (CollectionUtil.isNotEmpty(list)) {
            for (SupplierCompanyMaterialsSelfSupplyDto dto : list) {
                experimentMapper.updateBatchReportBySelfSupply(dto);
            }
        }
    }

    @Override
    public void updateBatchExperiment(Experiment experiment) {
        List<Experiment> experimentList = experimentMapper.getList(experiment);
        assertTrue(CollectionUtil.isEmpty(experimentList), "通过条件未找到试验台账数据");
        Experiment entity = new Experiment().setId(experimentList.get(0).getId()).setSelfSupply(experiment.getSelfSupply());
        experimentMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public void submitShxhSynchronizedata(ShxhSynchronizedata entity) {
        Long experimentId = entity.getExperimentId();
        Experiment experiment = this.loadById(experimentId);
        assertTrue(experiment == null, "试验委托信息不存在");
        String consignId = entity.getConsignId();
        String sampleId = entity.getSampleId();
        /** 根据样品编号查询 WT_SAMPLE表  **/
        String importId = wtSampleMapper.findImportIdWTSample(sampleId);
        /** 混凝土不做校验 **/
        if (!experiment.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            assertTrue(StringUtils.isBlank(importId), "协会进料信息不存在");
            importId = importId.replace(";", "");
        }
        if (StringUtils.isBlank(importId)) {
            importId = null;
        }
        ShxhSynchronizedata shxhSynchronizedata = shxhSynchronizedataMapper.selectByExperimentIdOne(experimentId);
        if (shxhSynchronizedata == null) {
            ShxhSynchronizedata insert = new ShxhSynchronizedata();
            insert.setExperimentId(experimentId);
            insert.setConsignId(consignId);
            insert.setSampleId(sampleId);
            insert.setFinistStatus("0");
            insert.setImportId(importId);
            shxhSynchronizedataMapper.insertSelective(insert);
        } else {
            ShxhSynchronizedata update = new ShxhSynchronizedata();
            update.setImportId(importId);
            update.setConsignId(consignId);
            update.setSampleId(sampleId);
            update.setId(shxhSynchronizedata.getId());
            shxhSynchronizedataMapper.updateByPrimaryKeySelective(update);
        }
    }

    @Override
    public void generateReport(Long id) {
        /** 判断：sample_stauts = 2 或者 3  &&  stauts不包含0，则执行下面操作*/
        Experiment experiment = experimentMapper.findExperimentById(id);
        List<ShxhSynchronizedata> list = shxhSynchronizedataMapper.getList(new ShxhSynchronizedata().setExperimentId(id));
        assertTrue(list.isEmpty() || list.get(0).getSampleNo() == null || list.get(0).getImportId() == null || list.get(0).getConsignId() == null
                || list.get(0).getSampleId() == null, "生成报告失败，请先上传该委托！");

        ShxhSynchronizedata synchronizedata = list.get(0);
        //上海协会对应的样品编码
        String sampleNo = synchronizedata.getSampleId();
        Map<String, Object> wtSampleList = wtSampleMapper.findWTSampleList(sampleNo);
        assertTrue(wtSampleList.isEmpty() || !wtSampleList.containsKey("Sample_ID"), "生成报告失败，请先上传该委托！");
        /** 判断：sample_stauts = 2 或者 3  &&  stauts不包含0*/
        if (!wtSampleList.get("Status").toString().contains("0") && (wtSampleList.get("Sample_Status").toString().equals("1") || wtSampleList.get("Sample_Status").toString().equals("2") || wtSampleList.get("Sample_Status").toString().equals("3"))) {
            //判断序号表是新增还是修改
            boolean isUpdateSn = false;
            //根据台账 查询品控做的试验项目详情 结果
            List<ExperimentDetail> experimentDetailList = experimentDetailMapper.getList(new ExperimentDetail().setExperimentId(experiment.getId()));

            com.alibaba.fastjson.JSONArray objArray = new com.alibaba.fastjson.JSONArray();
            for (ExperimentDetail experimentDetail : experimentDetailList) {
                objArray.add(experimentDetail.getObjJson());
            }
            Date jcrq = ExperimentDetail.extractEndDate(objArray);
            //根据进料id查询进料数据
            List<String> stringList = new ArrayList<>();
            stringList.add(synchronizedata.getImportId());
            List<ImportList> mapList = importListMapper.findImportListById(stringList);
            PrintReport report = printReportMapper.queryByConSignID(synchronizedata.getConsignId());
            if (report == null) {
                report = new PrintReport();
                String reportNo = ReportIdEnum.selectByCode(experiment.getExperimentType()).getNo();

                report.setConSignID(synchronizedata.getConsignId());
                report.setImportId(synchronizedata.getImportId());
                report.setKindID(mapList.get(0).getKindId());
                report.setItemID(mapList.get(0).getItemId());
                PrintReportSerialNumber printReportSerialNumber = printReportMapper.queryReportSerialNumberByItemID(report.getItemID());
                String reportId = "";
                Integer currentSN;
                if (printReportSerialNumber == null) {
                    printReportSerialNumber = new PrintReportSerialNumber();
                    printReportSerialNumber.setCurrentSN(0);
                    printReportSerialNumber.setItemID(Integer.valueOf(report.getItemID()));
                    printReportSerialNumber.setCurrentYear(DateHelper.getYear());
                    printReportSerialNumber.setPreName(reportNo);
                    reportId = reportNo + DateHelper.getYear() + "00001";
                } else {
                    currentSN = printReportSerialNumber.getCurrentSN();
                    int maxId = currentSN + 1;
                    String currentNumber = String.format("%05d", maxId);
                    printReportSerialNumber.setCurrentSN(maxId);
                    isUpdateSn = true;
                    reportId = reportNo + DateHelper.getYear() + currentNumber;
                }
                report.setReportID(reportId);
                savePrintReport(report, experiment, jcrq, isUpdateSn, printReportSerialNumber, sampleNo);
            } else {
                experiment.setReportNo(report.getReportID());
                experimentMapper.updateByPrimaryKeySelective(experiment);
            }
            List<AssociationStorage> associationStorageList = associationStorageMapper.getList(new AssociationStorage().setExperimentId(experiment.getId()));
            if (associationStorageList == null || associationStorageList.isEmpty()) {
                AssociationStorage storage = new AssociationStorage()
                        .setExperimentId(experiment.getId())
                        .setGradeId(null)
                        .setSampleId(StringUtils.isNotBlank(sampleNo) ? Long.valueOf(sampleNo) : null)
                        .setSpecId(null)
                        .setReportId(report.getReportID());
                associationStorageMapper.insertSelective(storage);
            } else {
                AssociationStorage storage = associationStorageList.get(0);
                storage.setReportId(report.getReportID());
                associationStorageMapper.updateByPrimaryKeySelective(storage);
            }
            WtConsign wtConsign = new WtConsign();
            wtConsign.setConSignId(synchronizedata.getConsignId());
            String examConclusion = sampleNo + ":所检项目合格;";
            /** 水泥：3天强度报告有数据，且28天强度没数据，Exam_Conclusion=样品编号+":"+"此报告仅供参考，以二十八天强度报告为准。*/
            if (MaterialsEnum.CEMENT.getCode().equals(experiment.getExperimentType()) && isSnTestPojector(experimentDetailList)) {
                examConclusion = sampleNo + ":此报告仅供参考，以二十八天强度报告为准。";
            }
            wtConsign.setExamConclusion(examConclusion);

            //更新协会wt 报告编号
            consignMapper.updateWtConsign(report.getReportID(), report.getConSignID(), examConclusion);

            //更新协会wt 报告编号
            importListMapper.updateImportListReportID(report.getReportID(), report.getImportId());
        }
    }


    @Override
    public void viewNewTask(Long id) {
        Experiment experiment = experimentMapper.loadById(id);
        assertTrue(experiment == null, "试验台账信息不存在");
        experiment.setIsNewTask(0);
        experiment.init(false);
        experimentMapper.updateByPrimaryKeySelective(experiment);

        Integer experimentType = experiment.getExperimentType();
        if (experimentType.equals(MaterialsEnum.CONCRETE.getCode())) {
            experimentTaskMapper.updateReadTimeIsNull(id);
        } else {
            experimentSupplyTaskMapper.updateReadTimeIsNull(id);
        }
    }

    @Override
    public void revokeUpload(Long id) {
        Experiment experiment = experimentMapper.loadById(id);
        assertTrue(experiment.getEntrustExperiment().contains("氯离子含量"), "氯离子含量试验台账不支持撤销上传");
        ShxhSynchronizedata shxhSynchronizedata = shxhSynchronizedataMapper.selectByExperimentIdOne(id);
        /**校验同类型原材料是不是最后一批委托，最后一批才允许撤销 */
        String sampleId;
        if (experiment.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
            assertTrue(experiment.getEntrustExperiment().contains("氯离子含量"), "氯离子含量试验台账不支持撤销上传");
            /** 混凝土*/
            if (experiment.getEntrustExperiment().contains("抗压强度")) {
                sampleId = experimentMapper.getLastExperimentByTypeConcrete("抗压强度");

            } else if (experiment.getEntrustExperiment().contains("抗渗等级")) {
                sampleId = experimentMapper.getLastExperimentByTypeConcrete("抗渗等级");
                assertTrue(!experimentMapper.getLastExperimentByTypeConcrete("抗渗等级").equals(shxhSynchronizedata.getSampleNo()), "不是最后一批委托不支持撤销上传");
            } else if (experiment.getEntrustExperiment().contains("抗折强度")) {
                sampleId = experimentMapper.getLastExperimentByTypeConcrete("抗折强度");
                assertTrue(!experimentMapper.getLastExperimentByTypeConcrete("抗折强度").equals(shxhSynchronizedata.getSampleNo()), "不是最后一批委托不支持撤销上传");
            } else {
                sampleId = null;
                assertTrue("该试验台账不支持撤销上传");
            }
        } else {
            /** 原材料*/
            sampleId = experimentMapper.getLastExperimentByType(experiment.getExperimentType());
        }
        assertTrue(!sampleId.equals(shxhSynchronizedata.getSampleId()), "不是最后一批委托不支持撤销上传");
        /**删除pk_shxh_synxxxx表的数据 */
        shxhSynchronizedataMapper.delete(shxhSynchronizedata);
    }

    //判断对应实验项目是否存在平均值
    private boolean isSnTestPojector(List<ExperimentDetail> experimentDetailList) {
        for (ExperimentDetail detail : experimentDetailList) {
            JSONObject objJson = detail.getObjJson();
            //凝结时间
            if (detail.getTestProjectCode().equals(CementEnum.QDCD.getTestProjectType())) {
                CementQdcd cementQdcd = JsonUtils.getObject(objJson, CementQdcd.class);
                CementQdcd.Kyqdsy kyqdsy3d = cementQdcd.getKyqdsy3d();
                CementQdcd.Kyqdsy kyqdsy28d = cementQdcd.getKyqdsy28d();
                if (!NullUtils.isNull(kyqdsy3d.getPjz()) && NullUtils.isNull(kyqdsy28d.getPjz())) {
                    return true;
                }
            }
        }
        return false;
    }


    private void savePrintReport(PrintReport report, Experiment experiment, Date jcrq, boolean isUpdateSn, PrintReportSerialNumber printReportSerialNumber, String sampleNo) {
        log.info("开始操作协会【Print_Report】表数据");
        /** 所有的原材料报告，报告日期为最后一天检测日期 **/
        Date reportDate = experiment.getExperimentType() == 7 ? new Date() : jcrq;
        if (isUpdateSn) {
            printReportMapper.updateReportSerialNumber(printReportSerialNumber);
        } else {
            printReportMapper.insertReportSerialNumber(printReportSerialNumber);
        }
        /**暂定验证码生成规则为 itemId+1442+四位随机数+四个空格 **/
        report.setIdentifyingCode(report.getItemID() + "1442" + new Random().nextInt(9000) + "    ");
        report.setReportCreateDate(jcrq);
        report.setReportAuditTime(jcrq);
        report.setReportCreateTime(new Date());
        report.setReportCreatePerson(experiment.getSocietyUserName());
        report.setProjectID("1");
        report.setReportAuditId("0");
        report.setReportAudit("1");
        report.setReportAuditLoginType("0");
        report.setReportSendOut("0");
        report.setPrintStatus("0");
        report.setGetReportType("自取");
        report.setUploadFlag(UploadFlagUtils.CtoGB_Num(report.getConSignID(), "z", new Date(), null));
        PrintReport printReportOld = printReportMapper.queryByConSignID(report.getConSignID());
        if (printReportOld == null) {
            printReportMapper.insertPrintReport(report);
            experimentMapper.updateByPrimaryKeySelective(new Experiment().setId(experiment.getId()).setReportNo(report.getReportID()).setReportDate(reportDate));
        } /*李总确认目前只新增，不修改
        else {
            report.setID(printReportOld.getID());
            printReportMapper.updatePrintReport(report);
        }*/
        log.info("操作协会【Print_Report】表成功，入参：【{}】", JsonUtils.getJson(report));

        log.info("开始操作协会【print_examrecord】表数据");
        //保存打印记录表

        PrintExamRecord printExamRecordOld = printReportMapper.queryBySampleID(sampleNo, report.getConSignID());
        PrintExamRecord printExamRecord = new PrintExamRecord();
        printExamRecord.setKindID(report.getKindID());
        printExamRecord.setItemID(report.getItemID());
        printExamRecord.setConSignID(report.getConSignID());
        printExamRecord.setSampleID(sampleNo);
        printExamRecord.setExamPerson(experiment.getSocietyUserName());
        printExamRecord.setExamTime(jcrq);
        printExamRecord.setPrintStatus("0");
        printExamRecord.setReportApproval("1");
        printExamRecord.setReportApprovalLoginType("0");
        printExamRecord.setReportApprovalTime(jcrq);
        printExamRecord.setUploadFlag(UploadFlagUtils.CtoGB_Num(sampleNo, "z", new Date(), null));
        if (printExamRecordOld == null) {
            printReportMapper.insertPrintExamRecord(printExamRecord);
        }
    }

    /**
     * 新增试验委托相关信息和模拟生成供货任务信息
     *
     * @param createMaterialsExperimentVo 入参
     * @param checkThreshold              阈值=代表数量
     * @param materialsSpecConfig         材料信息
     * @param materialsList               物料信息
     */
    private void insertExperimentAndSupplyTask(CreateMaterialsExperimentVo createMaterialsExperimentVo, Double checkThreshold, MaterialsSpecConfig materialsSpecConfig, List<Materials> materialsList) {
        Set<String> testProjectCodeList = createMaterialsExperimentVo.getTestProjectCodeList();
        /**组装试验委托信息*/
        Experiment experiment = CreateMaterialsExperimentVo.payloadExperiment(createMaterialsExperimentVo, checkThreshold);
        experiment.init(true);
        this.payloadOtherInfo(experiment, testProjectCodeList);

        if (materialsSpecConfig != null) {
            experiment.setMaterialsName(materialsSpecConfig.getMaterialsName());
            experiment.setMaterialsSpecs(materialsSpecConfig.getMaterialsSpec());
            if (StringUtils.isNotEmpty(materialsSpecConfig.getMaterialAbbreviation())) {
                experiment.setSampleLevel(materialsSpecConfig.getMaterialAbbreviation() + materialsSpecConfig.getMaterialsSpec());
                experiment.setMaterialAbbreviation(materialsSpecConfig.getMaterialAbbreviation());
            } else {
                experiment.setSampleLevel(materialsSpecConfig.getMaterialsName() + materialsSpecConfig.getMaterialsSpec());
                /**简称没有直接赋值全称*/
                experiment.setMaterialAbbreviation(materialsSpecConfig.getMaterialsName());
            }
        }

        if (materialsList.isEmpty()) {
            experiment.setMatterName(experiment.getMaterialsName());
            experiment.setMatterSpecs(experiment.getMaterialsSpecs());
            experiment.setMatterAbbreviation(experiment.getMaterialAbbreviation());
        }
        /* 绑定物料的操作是在运单绑定的接口中，注销掉逻辑
        else {
            Materials materials = materialsList.get(0);
            List<Long> materialsIdList = materialsList.stream().map(Materials::getId).collect(Collectors.toList());
            experiment.setMaterialsId(materialsIdList.stream().map(String::valueOf).collect(Collectors.joining(",")));
            experiment.setMatterName(materials.getMaterialName());
            experiment.setMatterSpecs(materials.getMaterialSpecs());
            experiment.setMatterAbbreviation(materials.getMaterialAbbreviation());
        }*/

        /**这里查询供应商简称*/
        SupplierCompany supplierCompany = supplierCompanyMapper.selectBySupplierName(experiment.getSupplyCompanyName());
        if (supplierCompany != null) {
            experiment.setSupplyCompanyName(supplierCompany.getErpCompanyName());
            experiment.setSupplyCompanyCalled(supplierCompany.getSupplierAbbreviation());
            experiment.setCertificateNo(supplierCompany.getCertificateNo());
        }

        if (StringUtils.isNotBlank(experiment.getMaterialsId())) {
            /**给新加的是否甲供字段赋值*/
            SupplierCompanyMaterialsSelfSupplyDto supplierCompanyMaterialsSelfSupplyDto = new SupplierCompanyMaterialsSelfSupplyDto().
                    setMaterialsId(Long.valueOf(experiment.getMaterialsId()))
                    .setSpecId(experiment.getSpecId())
                    .setSupplierCompanyName(experiment.getSupplyCompanyName())
                    .setManufacturers(experiment.getFactory())
                    .setManufacturersCalled(experiment.getFactoryCalled());
            List<SupplierCompanyMaterialsSelfSupplyDto> selfSupplyList = supplierCompanyMaterialsMapper.getMaterialsSelfSupplyList(supplierCompanyMaterialsSelfSupplyDto);
            if (CollectionUtil.isNotEmpty(selfSupplyList)) {
                experiment.setSelfSupply(SelfSupplyEnum.YES.getCode());
            } else {
                experiment.setSelfSupply(SelfSupplyEnum.NO.getCode());
            }
        }

        experimentMapper.insertSelective(experiment);

        this.initExperimentTestProject(experiment, testProjectCodeList);
        /**新增试验台账消息通知记录*/
        experimentMessageService.saveExperimentMessage(experiment);

        Long experimentId = experiment.getId();

        /**新增试验台账与电子签名关系记录*/
        ExperimentSignature experimentSignature = new ExperimentSignature();
        experimentSignature.setExperimentId(experimentId);
        Signature signature = signatureMapper.loadById(1L);
        if (signature != null) {
            experimentSignature.setSignatureJson(JsonUtils.beanToObject(signatureMapper.loadById(1L)));
        }
        experimentSignatureMapper.insert(experimentSignature);

        /**模拟创建供货任务*/
        Long taskId = supplyTaskService.insertSupplyTaskByExperiment(experiment);

        /**新增试验委托和供货任务的关系*/
        if (taskId != null) {
            ExperimentSupplyTask experimentSupplyTask = new ExperimentSupplyTask();
            experimentSupplyTask.setExperimentId(experimentId);
            experimentSupplyTask.setSupplyTaskId(taskId);

            if (experimentSupplyTaskMapper.selectOne(experimentSupplyTask) == null) {
                experimentSupplyTask.setCreateTime(new Date());
                experimentSupplyTask.setReadTime(null);
                experimentSupplyTaskMapper.insertSelective(experimentSupplyTask);

                /**这里新增任务单的关联关系 给对应试验委托的isNewTask改为1*/
                log.info(this.getClass().getName() + "insertExperimentAndSupplyTask.class新增任务单给对应isNewTask修改为1");
                experimentMapper.updateIsNewTask(experimentId, 1);


                // log.info(this.getClass().getName() + ".insertExperimentAndSupplyTask.class新增任务单之后，推送协会！");
                /**推送到协会，这里新增任务单 状态为自动上传*/
                // syncProcessorService.submitRequest(new UploadLaboratoryEntity().setExperimentId(Collections.singletonList(String.valueOf(experimentId))).setUploadState(1));
            }
        }
    }
}
